在 [DAY 4] 讓我們可以帶著資料走的變數 時我們曾經提到:
對於大多數的程式語言來說,一旦我們在宣告中指定了這個變數的資料型態後便不能改變,也就是說,我們不能把其他資料型態的資料輸入到這個變數中,只能使用這個變數來儲存它被指定的資料型態的資料。
那是否就意味著我們不能把不同的資料型態的資料放在一起使用呢?今天我們要討論的**型態變換 (Type Casting/Conversion)**便是解答這個問題的關鍵了。
在一般的情況下,如果我們想要強行的讓兩個不同資料型態的變數放在同一個運算式來使用的話,像是下面的例子,大多數的程式語言都只會彈出錯誤的訊息。這是因為程式沒有辦法像我們一樣把接收到資料進行解讀並自行理解它的意思,即使我們輸入了屬於數字的文字,對於程式來說,那也只是一個沒有任何意思的文字資料而已。
int sum = 1 + "1"; // 錯誤!
因此,我們需要提示程式這個被輸入的資料有著可以同時以其他的資料型態來表示它的值的可能性,讓程式去嘗試把這個資料轉換到其他的資料型態,這就是變數的型態變換。透過型態變換,我們便可以使用原來是不同資料型態的變數來進行更多的運算行為。而對於不同類型的變數的型態變換,我們使用的方法都不一樣:
語法剖析器是大多數程式語言用來分析文字來轉換成其他的資料型態的工具,因此,我們在把字元或字串資料型態的變數進行型態變換時官方所提供的工具通常都會包含了**分析 (parse) **這個字。
在 Java 中使用語法剖析器的例子:
int sum = 1 + Integer.parseInt("1"); // 結果為 2
在 C# 中使用語法剖析器的例子:
int sum = 1 + int.Parse("1"); // 結果為 2
擴展轉換是數字類的資料型態之間的常見轉換方法之一,常用於算術運算子中。一般用於把包含較小的數值範圍的資料型態轉換為包含較大的數值範圍的資料型態。由於資料中的數值一定能包含在轉換後的資料型態的數值範圍中,因此在擴展轉換的過程中,資料的數值能被完整地保留。
常見的資料型態可進行擴展轉換的順序 (可從左邊的資料型態轉換至右邊的任意資料型態):
short > int > long > float > double
在 C 中使用擴展轉換的例子:
int number = 10;
printf("%f", (double)number / 4); // 結果為 2.500000 (數值能被完整地保留)
縮小轉換也是數字類的資料型態之間的常見轉換方法之一,常用於算術運算子中。跟擴展轉換相反,一般用於把包含較大的數值範圍的資料型態轉換為包含較小的數值範圍的資料型態。由於資料中的數值不一定能包含在轉換後的資料型態的數值範圍中,因此在縮小轉換的過程中,必須注意資料的數值可能出現失去精度或部分資訊,如從 float 轉換為 int 資料型態時有些程式語言會自動進行四捨五入或無條件捨去的計算處理,或是出現溢數 (Overflow) 的錯誤。
常見的資料型態可進行縮小轉換的順序 (可從左邊的資料型態轉換至右邊的任意資料型態):
double > float > long > int > short
在 C 中使用縮小轉換的例子:
double number = 10.0;
printf("%d", (int)number / 4); // 結果為 2 (小數被無條件捨去)
任何資料型態的資料都可以以文字的方式來進行表示,因此,把其他資料型態的資料轉換為字串資料型態並沒有什麼的限制,一般來說,直接把資料轉換為字串資料型態的功能大多會被命名為 ToString。有些程式語言則針對字串資料型態的轉換提供了格式化字串的功能,透過格式化字串 (Format String) 功能,我們可以自訂該段文字的表示格式,如控制要顯示小數位數的數量或日期的顯示順序等。大家對格式化字串有興趣的話,可以到微軟的官方文檔中了解到一些常見的格式化字串的例子。
延伸閱讀:
微軟 - 概觀:如何在 .NET 中格式化數位、日期、列舉和其他類型:https://learn.microsoft.com/zh-tw/dotnet/standard/base-types/formatting-types